package com.funcity.stage
{
	import com.funcity.cache.ResourceCacher;
	import com.funcity.events.CacheEvent;
	import com.funcity.stage.layers.CloudLayer;
	import com.funcity.stage.layers.GroundLayer;
	import com.funcity.stage.layers.StageLayer;
	import com.greensock.TweenLite;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.ByteArray;
	
	public final class GameStage extends Sprite
	{
		private static const STAGE_WIDTH:uint = 1500;
		private static const STAGE_HEIGHT:uint = 900;

		// ground layer manages stage map loading
		private var _baseGround:Bitmap = new Bitmap();
		private var _groundLayer:GroundLayer = new GroundLayer();
		
		// stage layer manage all element on stage
		private var _stageLayer:StageLayer;
		
		// cloud layer manages flying and weather
		private var _cloudLayer:CloudLayer;
		
		private var _mapURL:String;
		private var _width:uint = 0;
		private var _height:uint = 0;
		
		private var _stepX:uint = 0;
		private var _stepY:uint = 0;
		
		private var _curPix:Point = new Point(0, 0);
		
		public function GameStage(clouds:Vector.<BitmapData>)
		{
			super();
			
			_stageLayer = new StageLayer();
			_cloudLayer = new CloudLayer(STAGE_WIDTH, STAGE_HEIGHT, clouds);
			
			addChild(_baseGround);
			addChild(_groundLayer);
			addChild(_stageLayer);
			addChild(_cloudLayer);
			
			addEventListener(MouseEvent.CLICK, onClick);
			
			var initInd:uint = 0;
			addEventListener(Event.ADDED_TO_STAGE, 
			function init(e:Event):void
			{
				initInd = ++initInd % 2;
				if(initInd == 1) return;
				
				stage.addEventListener(Event.RESIZE,
				function resize(e:Event):void
				{
					centerTo(_curPix.x, _curPix.y);
				});
			});
		}
		
		public function changeMap(map:String):void
		{
			if (_mapURL)
			{
				var url:String = _mapURL +"/wall.dat";
				ResourceCacher.instance.cancel(url);
			}
			_mapURL = "map/" + map;
			
			loadMapInfo();
		}
		
		public function move(xPos:Number, yPos:Number):void
		{
			//_cloudLayer.drawCloudMasker(false); // draw cloud masker
			
		}
		
		
		public function centerTo(xcP:Number, ycP:Number):void
		{
			//计算边界
			var bounded:Point = checkCenterBound(
				new Point(xcP, ycP),
				new Rectangle(0,0,stage.stageWidth, stage.stageHeight),
				new Rectangle(0,0,_width,_height));
			//记录stage中心
			_curPix.x = bounded.x;
			_curPix.y = bounded.y;
			//移动地图
			_groundLayer.centerTo(bounded.x, bounded.y);
		}
		
		
		/**
		 * 检查中心点的边界
		 * 
		 * @param centerPoint view的中心点在scene上的位置
		 * @param view 当前能看到的场景大小
		 * @param scene 整个场景大小
		 * @return 不会越界的中心点在scene上的位置
		 * 
		 */		
		public static function checkCenterBound(centerPoint:Point, view:Rectangle, scene:Rectangle):Point
		{
			//假设场景会小于可视范围stage
			//dnf这样的横版可能高度小于stage，雷电这样竖版的可能宽度小于stage。
			//肯定是直接吧场景居中到可视范围的。
			if(view.width > scene.width) view.width = scene.width;
			if(view.height > scene.height) view.height = scene.height;
			
			var ltPoint:Point = new Point();
			ltPoint.x = view.width / 2;
			ltPoint.y = view.height / 2;
			
			var rbPoint:Point = new Point();
			rbPoint.x = scene.width - view.width / 2;
			rbPoint.y = scene.height - view.height / 2;
			
			var boundPoint:Point = new Point();
			boundPoint.x = centerPoint.x;
			boundPoint.y = centerPoint.y;
			
			if(centerPoint.x < ltPoint.x) boundPoint.x = ltPoint.x;
			if(centerPoint.y < ltPoint.y) boundPoint.y = ltPoint.y;
			if(centerPoint.x > rbPoint.x) boundPoint.x = rbPoint.x;
			if(centerPoint.y > rbPoint.y) boundPoint.y = rbPoint.y;
			
			return boundPoint;
		}
		
		private function loadMapInfo():void
		{
			var url:String = _mapURL +"/wall.dat";
			ResourceCacher.instance.loadBinary(url,
			function handleMapInfo(data:ByteArray):void
			{
				data.uncompress();
				
				data.readInt(); // read map id, ignore it
				
				_width = data.readInt(); // read map width
				_height = data.readInt(); // read map height
	
				_stepX = data.readInt(); // read _stepX
				_stepX = data.readInt(); // read _stepY
				
				var list:Array = data.readObject(); // read map mask items
				
				loadMiniMap(); // load mini map firstly
				
				_groundLayer.changeMap(_mapURL, 100, 100); // load groud tiles
				centerTo(100,100);
				//_stageLayer.maskers = list; // init stage maskers
				//_cloudLayer.drawCloudMasker(false); // draw cloud masker
			});
		}
		
		private function loadMiniMap():void
		{
			var url:String = _mapURL + "/mini.jpg";
			ResourceCacher.instance.loadImage(url, 
			function handleMiniMap(data:*):void
			{
				_baseGround.bitmapData = BitmapData(data);
				_baseGround.width = _width;
				_baseGround.height = _height;
			});
		}
		

		
		private var _xCenter:int = 500;
		private var _yCenter:int = 300;
		
		
		private var ax:Number = 400;
		private var ay:Number = 300;
		private function onClick(e:MouseEvent):void
		{
//			var xCenter:Number = e.localX - _baseGround.x;
//			var yCenter:Number = e.localY - _baseGround.y;
//			
//			_baseGround.x - (xCenter - _xCenter);
//			_baseGround.y - (yCenter - _yCenter);
			
			centerTo(ax,ay);
			ax = ax + 100;
			ay = ay + 100;
			//_groundLayer.scale = 0.5;
		}
	}
}